#include "Session.h"
#include <iostream>
using namespace std;
/*
客户端          服务器
   |              |
   |              |--- 1. Start(): 清空缓冲区
   |              |--- 2. async_read_some: 等待数据
   |              |
   |--发送数据--->|
   |              |--- 3. handle_read: 收到数据
   |              |--- 4. async_write: 开始发送响应
   |              |--- 5. 打印发送数据
   |<--收到响应---|
   |              |--- 6. handle_write: 清空缓冲区
   |              |--- 7. async_read_some: 等待新数据
   |              |
   |--发送数据--->|    (循环继续...)
*/
/*
代码流程
1. 开始会话：
当一个新的客户端连接到服务器时，Session::Start 被调用。
这会启动一个异步读取操作，等待客户端发送数据。
2. 读取数据：
当客户端发送数据到服务器时，handle_read 被调用。
如果读取成功（没有错误），服务器会打印接收到的数据，
并启动一个异步写入操作，将数据发送回客户端。
3. 写入数据：
当数据成功写回客户端时，handle_write 被调用。
如果写入成功（没有错误），服务器会清空数据缓冲区，并再次启动异步读取操作，准备接收新的数据。
*/

// 开始会话，初始化数据缓冲区并开始异步读取数据
void Session::Start()
{
	// 清空数据缓冲区
	memset(_data, 0, max_length);
	// 启动异步读取操作，完成后调用handle_read回调函数
	_socket.async_read_some(boost::asio::buffer(_data, max_length),
							std::bind(&Session::handle_read, this, placeholders::_1,
									  placeholders::_2));
}

// 处理异步读取完成后的回调
void Session::handle_read(const boost::system::error_code &error, size_t bytes_transfered)
{
	if (!error)
	{
		// 打印接收到的数据
		cout << "server receive data is " << _data << endl;
		// 将接收到的数据异步写回客户端，完成后调用handle_write回调函数
		boost::asio::async_write(_socket, boost::asio::buffer(_data, bytes_transfered),
								 std::bind(&Session::handle_write, this, placeholders::_1));
		cout << "async_write " << _data << endl;
	}
	else
	{
		// 发生错误时释放Session对象
		delete this;
	}
}

// 处理异步写入完成后的回调
void Session::handle_write(const boost::system::error_code &error)
{
	if (!error)
	{
		// 清空数据缓冲区
		memset(_data, 0, max_length);
		// 继续读取新的数据 如果客户端不关闭 还是可以继续收消息的
		_socket.async_read_some(boost::asio::buffer(_data, max_length),
								std::bind(&Session::handle_read,
										  this, placeholders::_1, placeholders::_2));
	}
	else
	{
		// 发生错误时释放Session对象
		delete this;
	}
}

// Server类构造函数：初始化io_context和acceptor
Server::Server(boost::asio::io_context &ioc, short port) : _ioc(ioc),
														   _acceptor(ioc, tcp::endpoint(tcp::v4(), port))
{
	// 开始接受新的连接
	start_accept();
}

// 开始接受新的客户端连接
void Server::start_accept()
{
	// 创建新的Session对象
	Session *new_session = new Session(_ioc);
	// 异步接受连接，完成后调用handle_accept回调函数
	_acceptor.async_accept(new_session->Socket(),
						   std::bind(&Server::handle_accept, this, new_session, placeholders::_1));
}

// 处理新连接接受完成后的回调
void Server::handle_accept(Session *new_session, const boost::system::error_code &error)
{
	if (!error)
	{
		// 连接成功，启动会话
		new_session->Start();
	}
	else
	{
		// 发生错误，清理Session对象
		delete new_session;
	}

	// 继续接受下一个连接
	start_accept();
}
